Public Class frmMain
    'TODo: Set up settings so that serial applies to entire computer, not just current windows user

    Private butMatches(0) As Button     ' Will be Re-Dimensioned to be appropriate size as needed

#Region "Static Event Handlers"
    Private Sub frmMain_Activated(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Activated
        ' Purpose:
        '   Handles event when user moves focus back to this form

        Me.Opacity = 1.0 ' Show when activated
    End Sub


    Private Sub frmMain_Deactivate(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Deactivate
        ' Purpose:
        '   Handles event when user moves focus away from this form

        Me.Opacity = 0.3 ' Go semi-transparent when not using program
    End Sub

    Private Sub frmMain_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        ' If started as tray application then behave as such
        '   Do not close until right-clicked on tray context menu to close
        If g_isTrayMode Then
            Me.WindowState = FormWindowState.Minimized
            e.Cancel = True
        End If
    End Sub

    Private Sub frmMain_HelpButtonClicked(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles Me.HelpButtonClicked
        Call gotoHelpWebsite()
    End Sub

    Private Sub frmMain_HelpRequested(ByVal sender As Object, ByVal hlpevent As System.Windows.Forms.HelpEventArgs) Handles Me.HelpRequested
        Call gotoHelpWebsite()
    End Sub

    Private Sub frmMain_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles Me.KeyPress
        displayMatchesFor(e.KeyChar.ToString)
    End Sub

    Private Sub frmMain_Layout(ByVal sender As Object, ByVal e As System.Windows.Forms.LayoutEventArgs) Handles Me.Layout
        ' Minimized has been queued therefore process...
        If g_isTrayMode And g_isQueuedToMinimize Then
            Me.WindowState = FormWindowState.Minimized
            g_isQueuedToMinimize = False
        End If
    End Sub


    Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ' Purpose:
        '   Initializes Form

        loadRecentResults() ' Load from settings recent results

        ' Toggle Tray Mode
        If Command() = "-m" Then
            g_isTrayMode = True
        Else
            g_isTrayMode = False
        End If

        ' Hide menu option to purchase if purchased
        If g_isPaidMode Then
            cmdPurchase.Visible = False
        End If

        ' Initialize title bars
        Me.sysTray.Text = My.Application.Info.AssemblyName
        Me.sysTray.BalloonTipTitle = My.Application.Info.AssemblyName
        Me.Text = My.Application.Info.AssemblyName

        ' Set Location
        Me.Top = Screen.PrimaryScreen.WorkingArea.Bottom - Me.Height - 25
        Me.Left = Screen.PrimaryScreen.WorkingArea.Right - Me.Width - 25

        ' Enable transparency settings
        Me.AllowTransparency = True
        Me.Opacity = 1.0

        ' Initialize system tray
        Me.sysTray.Icon = Me.Icon

        ' Initialize to last entered character (if one exists)
        If My.Settings.strLastEntry.Length > 0 Then
            displayMatchesFor(My.Settings.strLastEntry)
        End If

        ' Hide if initalizing to tray mode
        If g_isTrayMode Then
            Me.ShowInTaskbar = False
            g_isQueuedToMinimize = True
        End If
    End Sub

    Private Sub sysTray_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles sysTray.MouseClick
        ' Display form when user left-clicks on system tray icon
        If e.Button = Windows.Forms.MouseButtons.Left Then
            Me.Show()
            Me.WindowState = FormWindowState.Normal
        End If
    End Sub


    Private Sub txtInputChar_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtInputChar.TextChanged
        displayMatchesFor(txtInputChar.Text)
    End Sub

    Protected Overrides Sub Finalize()
        MyBase.Finalize()
    End Sub

    Public Sub New()

        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
    End Sub

    Private Sub frmMain_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize
        If g_isTrayMode AndAlso Me.WindowState = FormWindowState.Minimized Then
            ' Simply hide the application when in traystate and has been minimized
            Me.Hide()
        End If
    End Sub

    Private Sub tmrNag_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrNag.Tick
        ' Purpose: 
        '   Nag the user to purchase this program if they haven't already done so

        If g_isPaidMode Then
            tmrNag.Enabled = False
            Exit Sub
        End If

        ' Show balloon to buy if not purchased and using program
        If (Not g_isTrayMode And Not g_isPaidMode) Or g_isTrayMode And Me.WindowState = FormWindowState.Normal Then


            Me.sysTray.BalloonTipText = "I hope you enjoy using this program however it is not free." & _
                vbNewLine & vbNewLine & "Purchasing this program by right-clicking this icon and selecting 'Purchase' will remove this annoying message." & _
                vbNewLine & vbNewLine & "This message will be displayed again in " & tmrNag.Interval / 1000 & " seconds."
            Me.sysTray.ShowBalloonTip(30000)
        End If


    End Sub
#End Region

#Region "Code for displaying accents"
    Private Sub displayMatchesFor(ByVal strSymbol As String)
        ' Purpose:
        '   Display matching symbols given (nearly) any Unicode symbol

        ' Update the display if necessary
        If txtInputChar.Text <> strSymbol Then
            txtInputChar.Text = strSymbol
            My.Application.DoEvents()
        End If

        ' Actually Generate the buttons
        Dim objAccents As New clsAccents
        Dim strRawResults As String
        Dim strOptimizedResults As String

        strRawResults = objAccents.getSimilarUnicodeCharacters(strSymbol)
        strOptimizedResults = modRecent.getFinalResultsList(strSymbol, strRawResults)
        generateButtons(strOptimizedResults)

        ' Store this as the last used entry in settings
        My.Settings.strLastEntry = strSymbol
    End Sub


    Private Sub generateButtons(ByVal strFrom As String)
        ' Purpose:
        '   Generate buttons each containing 1 character from a string of characters provided in the parameter


        If Trim(strFrom) = "" Then
            Exit Sub
        End If

        ' Dispose of all existing buttons

        ' Each item in array will store 1 character as a Unicode String
        Dim intTotalItems As Integer = strFrom.Length
        Dim strSymbols(intTotalItems) As String
        Dim objParent As Panel

        objParent = pnlChoices

        ' Populate Array
        For intCounter As Integer = 0 To intTotalItems - 1
            strSymbols(intCounter) = strFrom.Substring(intCounter, 1)
        Next intCounter

        ' For faster processing, hide parent object
        objParent.Hide()
        My.Application.DoEvents()

        ' Dispose of old batch of buttons
        For intCounter As Integer = 0 To butMatches.GetUpperBound(0)
            Try
                butMatches(intCounter).Dispose()
            Catch
                ' Do nothing upon error except exit loop
                '   Exception ususally thrown during first run, could be corrected by to ... -1 but that creates a bug
                '   of not removing the last button of the last button set
                Exit For
            End Try
        Next intCounter

        ' Prepare for new batch of buttons
        ReDim butMatches(intTotalItems - 1)

        For intCounter As Integer = 0 To butMatches.GetUpperBound(0)
            ' Create the appropriate button
            butMatches(intCounter) = CreateButton(intCounter, strSymbols(intCounter))

            ' Create event handler for that new button so when the user clicks it, it actually does something useful!
            AddHandler butMatches(intCounter).Click, AddressOf SymbolClicked

            ' Set the parent object to the button appropriately
            butMatches(intCounter).Parent = objParent
        Next intCounter

        ' Show the hidden parent object
        objParent.Show()

        ' Set focus to the parent for intelliscroll compatibility
        objParent.Focus()

    End Sub

    Private Function CreateButton(ByVal intButtonNumber As Integer, ByVal strText As String) As Button
        ' Purpose:
        '   Create actual buttons for users to click on

        Const MAX_PER_ROW As Integer = 5    ' Maximum buttons per row
        Const SPACING As Integer = 5        ' Spacing between buttons in Pixels

        ' Create new button
        Dim butNew As New Button

        ' Set initial properties
        butNew.AutoEllipsis = False
        butNew.AutoSize = False
        butNew.Enabled = True
        butNew.Font = txtInputChar.Font
        butNew.FlatStyle = FlatStyle.Standard
        butNew.Height = 30
        butNew.TextAlign = ContentAlignment.MiddleCenter
        butNew.UseCompatibleTextRendering = False
        butNew.UseMnemonic = False
        butNew.UseVisualStyleBackColor = True
        butNew.Width = 30


        ' Determine X coordinate of button
        '   Use Modulus to determine column number
        butNew.Left = (intButtonNumber Mod MAX_PER_ROW) * (butNew.Width + SPACING) + SPACING ' Column Index (0-3) * Column Width 

        ' Determine Y coordinate of button
        '   Use Integer Divison to determine row number
        butNew.Top = (intButtonNumber \ MAX_PER_ROW) * (butNew.Height + SPACING) + SPACING ' Row Index (0 - Infinity) * Row Height

        ' Display strText
        butNew.Text = strText

        ' Reset Tab Stops
        butNew.TabStop = True
        butNew.TabIndex = intButtonNumber

        ' New button will be displayed automatically

        ' Return button so we can track its resource use, notably to delete it later on
        Return butNew
    End Function

    Private Sub SymbolClicked(ByVal sender As System.Object, ByVal e As System.EventArgs)
        ' Purpose:
        '   Handles event of accented character being clicked
        ' Preconditions:
        '   Event Handler dynamically created for all symbols
        ' Postconditions:
        '   Character copied to clipboard

        Dim strSymbol As String   ' String to copy to clipboard
        strSymbol = sender.text.ToString

        ' Copy text to clipboard as unicode
        My.Computer.Clipboard.SetText(strSymbol, TextDataFormat.UnicodeText)

        ' Record selection
        modRecent.addMatch(txtInputChar.Text, strSymbol)

        ' Display balloon
        Me.sysTray.BalloonTipIcon = ToolTipIcon.Info

        'ToDo: Fix bug where box is displayed for some symbols...
        Me.sysTray.BalloonTipText = strSymbol & " has been copied to the clipboard"
        Me.sysTray.ShowBalloonTip(1000)
    End Sub

    

#End Region

#Region "Popup Menu Static Event Handlers"
    Private Sub cmdAbout_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdAbout.Click
        AboutBox.Show()
    End Sub

    Private Sub cmdClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdClose.Click
        ' Force exit, override anything preventing us from terminating the program
        Me.Dispose()
        End
    End Sub

    Private Sub cmdHelp_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdHelp.Click
        Call gotoHelpWebsite()
    End Sub

    Private Sub cmdWebsite_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdWebsite.Click
        Call gotoProductWebsite()
    End Sub

    Private Sub cmdBlog_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdBlog.Click
        Call gotoBlogWebsite()
    End Sub

    Private Sub PurchaseToUnlockFeaturesToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdPurchase.Click
        SNForm.Show()
    End Sub

    Private Sub cmdPrivacy_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdPrivacy.Click
        gotoPrivacyPolicy()
    End Sub
#End Region


End Class
